﻿#include "ssRPCMgr.h"
#include "../time/ssTime.h"

namespace StarSeeker
{

ssRPCMgr::ssRPCMgr()
{
	m_timeOutMs = 30000;
	m_sn.Init(1, 100000000);
}

ssRPCMgr::~ssRPCMgr()
{
}

bool ssRPCMgr::IsRegistered(u32 cbMsgId)
{
	return m_allMsgID.find(cbMsgId) != m_allMsgID.end();
}

void ssRPCMgr::RegisterCallback(u32 sn, const RpcCallback& doFunc, u32 cbMsgId, i64 nowMs)
{
	if (nowMs == 0)
	{
		nowMs = ssTime::GetTimeNowMS().i64p;
	}
	CbFunc cbfunc{ nowMs + m_timeOutMs, sn, doFunc };
	std::map<u32, CbFunc>::iterator itr = m_cbMap.find(sn);
	if (itr != m_cbMap.end())
	{
		itr->second.func(eError::SN_REPEAT, 0, 0, 0);//SN失效回调
	}
	m_cbMap[sn] = cbfunc;
	m_cbList.push_back(std::make_pair(sn, cbfunc.timeOut));
	if (cbMsgId)
	{
		m_allMsgID.insert(cbMsgId);
	}
}

u32 ssRPCMgr::AutoRegister(const RpcCallback& doFunc, u32 cbMsgId, i64 nowMs)
{
	u32 sn = m_sn.GetID();
	RegisterCallback(sn, doFunc, cbMsgId, nowMs);
	return sn;
}

void ssRPCMgr::Update(i64 nowMs)
{
	for (size_t i = 0; i < 50; i++)
	{
		if (!m_cbList.empty())
		{
			std::pair<u32, i64>& ft = m_cbList.front();
			if (nowMs > ft.second)
			{
				std::map<u32, CbFunc>::iterator itr = m_cbMap.find(ft.first);
				if (itr != m_cbMap.end())
				{
					if (itr->second.timeOut == ft.second)
					{
						(itr->second.func)(eError::TIME_OUT, 0, 0, 0);//超时回调
						m_cbMap.erase(itr);
					}
				}
				m_cbList.pop_front();
			}
			else
			{
				break;
			}
		}
		else
		{
			break;
		}
	}
}

void ssRPCMgr::TriggerCallback(u32 sn, ulint param1, ulint param2, ulint param3)
{
	std::map<u32, CbFunc>::iterator itr = m_cbMap.find(sn);
	if (itr != m_cbMap.end())
	{
		(itr->second.func)(eError::OK, param1, param2, param3);
		m_cbMap.erase(itr);
	}
}

}
